import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { FriendApplication } from 'src/entities/friendApplication.entity';
import { User } from 'src/entities/user.entity';
import { ADDFRIENDENUM } from 'src/enum/addFriendEnum';
import { FriendDto } from 'src/friend/dto/friend.dto';
import { FriendService } from 'src/friend/friend.service';
import { SocketService } from 'src/socket/socket.service';
import { UserMessageService } from 'src/user-message/user-message.service';
import { UserService } from 'src/user/user.service';
import { Repository } from 'typeorm';
import { AddFriendDto } from './dto/add-friend.dto';
import { AgreeFriendDto } from './dto/agree_friend.dto';

@Injectable()
export class FriendApplicationService {
  constructor(
    private readonly userService: UserService,
    private readonly socketService: SocketService,
    private readonly friendService: FriendService,
    private readonly userMessageService: UserMessageService,
    @InjectRepository(FriendApplication)
    private friendApplicationRepository: Repository<FriendApplication>,
  ) {}

  async addFriend(addFriendDto: AddFriendDto) {
    let result = await this.friendService.findOne(
      addFriendDto.userId,
      addFriendDto.addFriendUserId,
    );
    if (result) {
      throw new HttpException('该用户已经是您的好友', HttpStatus.BAD_REQUEST);
    }
    let friend = await this.friendApplicationRepository.save(addFriendDto);
    let getNewUser = await this.findOne(friend.id);
    this.socketService.sendNewUserApprove(
      addFriendDto.addFriendUserId,
      getNewUser,
    );
    return true;
  }

  async agreeFriend(agreeFriendDto: AgreeFriendDto) {
    let result: FriendApplication =
      await this.friendApplicationRepository.findOne({
        where: { id: agreeFriendDto.id },
      });
    if (!result) {
      throw new HttpException('id is Not Fand', HttpStatus.BAD_REQUEST);
    }
    result.state = agreeFriendDto.state;
    if (result.state == ADDFRIENDENUM.AGREE) {
      let user1 = await this.userService.findOne(result.addFriendUserId);
      let user2 = await this.userService.findOne(result.userId);
      let setFriend: FriendDto = {
        userId: result.addFriendUserId,
        friendId: user2.id,
      };
      let setFriend2: FriendDto = {
        userId: result.userId,
        friendId: user1.id,
      };
      await this.friendService.save(setFriend);
      await this.friendService.save(setFriend2);
      await this.userMessageService.sendMessage({
        sendUserId: result.addFriendUserId,
        onUserId: user2.id,
        context: '添加好友成功,可以开始聊天了(*^_^*)',
        type: 'system',
      });
      await this.userMessageService.sendMessage({
        sendUserId: result.userId,
        onUserId: user1.id,
        context: '添加好友成功,可以开始聊天了(*^_^*)',
        type: 'system',
      });
      this.socketService.sendNewUser(result.addFriendUserId, user2);
      this.socketService.sendNewUser(result.userId, user1);
    }
    return this.friendApplicationRepository.save(result);
  }

  async findAll(userId: string) {
    let data = await this.friendApplicationRepository
      .createQueryBuilder('friendApplication')
      .where('friendApplication.addFriendUserId= :userId', { userId: userId })
      .leftJoinAndSelect(User, 'user', 'friendApplication.userId = user.id')
      .select([
        'friendApplication.id as id',
        'friendApplication.state as state',
        'user.id as userId',
        'user.userName as userName',
        'user.cetName as cetName',
        'user.mobile as mobile',
        'user.eMail as eMail',
        'user.headPhoto as headPhoto',
      ])
      .getRawMany();
    return data;
  }

  async findOne(id: string) {
    let data = await this.friendApplicationRepository
      .createQueryBuilder('friendApplication')
      .where('friendApplication.id= :id', { id: id })
      .leftJoinAndSelect(
        User,
        'user',
        'friendApplication.addFriendUserId = user.id',
      )
      .select([
        'friendApplication.id as id',
        'friendApplication.state as state',
        'user.id as userId',
        'user.userName as userName',
        'user.cetName as cetName',
        'user.mobile as mobile',
        'user.eMail as eMail',
        'user.headPhoto as headPhoto',
      ])
      .getRawOne();
    return data;
  }
}
